<template>
    <div class="flex flex-wrap gap-4">
        <!-- 查询表单区域 -->
        <el-card style="width: 100%" shadow="always">
            <el-form :inline="true" :model="queryForm" class="demo-form-inline">
                <el-form-item label="书名">
                    <el-input v-model="queryForm.bookName" placeholder="书名" clearable/>
                </el-form-item>
                <el-form-item label="作者">
                    <el-select v-model="queryForm.author" placeholder="作者" clearable>
                        <el-option v-for="item in authors" :key="item" :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="发布时间">
                    <el-date-picker v-model="queryForm.begin" type="datetime" placeholder="开始时间"
                        format="YYYY/MM/DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" :shortcuts="shortcuts" />
                    <span class="ml-2 mr-2">至</span>
                    <el-date-picker v-model="queryForm.end" type="datetime" placeholder="结束时间"
                        format="YYYY/MM/DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" :shortcuts="shortcuts" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="onSubmit">查询</el-button>
                    <el-button @click="onReset">清空</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <!-- 内容区域 -->
        <el-card style="width: 100%" shadow="always">
            <!-- 操作项 -->
            <div class="mb-4">
                <el-button type="primary" @click="openDialogForAdd">新增</el-button>
                <el-button type="danger" plain @click="toDeleteBatch">删除</el-button>
                <el-button type="success" plain>导入</el-button>
                <el-button type="primary" plain>导出</el-button>
                <div class="float-right cursor-pointer" @click="refresh">
                    <el-icon><RefreshLeft /></el-icon>
                </div>
            </div>
            <!-- 表格主体 -->
            <div>
                <el-table :data="booksData" max-height="760" border stripe style="width: 100%"
                    @selection-change="handleSelectionChange" 
                    :default-sort="{ prop: 'id', order: 'ascending' }">
                    <el-table-column type="selection" width="38" />
                    <el-table-column fixed="left" sortable prop="id" label="序号" width="80" />
                    <el-table-column prop="bookName" label="书名" width="250"/>
                    <el-table-column prop="author" label="作者" width="100"/>
                    <el-table-column prop="description" label="简介" />
                    <el-table-column prop="price" label="单价" width="70" />
                    <el-table-column prop="number" label="数量" width="60" />
                    <el-table-column prop="publishedDate" sortable label="发布时间" width="180" />
                    <el-table-column fixed="right" label="操作" width="136">
                        <template #default="scope">
                            <el-button size="small" type="info" plain 
                                @click="handleEdit(scope.$index, scope.row)">
                                编辑
                            </el-button>
                            <el-button size="small" type="danger"
                                @click="handleDelete(scope.$index, scope.row)">
                                删除
                            </el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
            <!-- 分页操作 -->
            <div class="mt-4">
                <el-pagination 
                    v-model:current-page="currentPage" 
                    v-model:page-size="pageSize" 
                    :total="total"
                    :page-sizes="[5, 10, 20, 50]" 
                    layout="total, sizes, prev, pager, next, jumper"
                    @size-change="handleSizeChange" @current-change="handleCurrentChange" />
            </div>
        </el-card>
    </div>

    <!-- 书籍表单 -->
    <el-dialog v-model="dialogFormVisible" :title="formTitle" draggable width="500" :before-close="toClose">
        <el-form :model="bookForm" label-position="top" :rules="rules" ref="rulesRef">
            <el-form-item>
                <el-input type="hidden"  v-model="bookForm.id" autocomplete="off"/>
            </el-form-item>
            <el-form-item label="书名" required prop="bookName">
                <el-input v-model.trim="bookForm.bookName" autocomplete="off"/>
            </el-form-item>
            <el-form-item label="作者" required prop="author">
                <el-input v-model.trim="bookForm.author" autocomplete="off"/>
            </el-form-item>
            <el-form-item label="简介">
                <el-input type="textarea" v-model="bookForm.description" autocomplete="off" />
            </el-form-item>
            <el-form-item label="价格&数量">
                <span class="mr-4">单价(元)</span>
                <el-input-number v-model.number.trim="bookForm.price" :precision="2" :step="0.1"/>
                <span class="ml-8 mr-4">数量(本)</span>
                <el-input-number v-model.number.trim="bookForm.number" :min="1"/>
            </el-form-item>
        </el-form>
        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="toSave">提交</el-button>
                <el-button type="info" plain @click="toClose">取消</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
import { onMounted } from 'vue'
import { 
    authorsRequest, 
    booksPageRequest, 
    addBookRequest, 
    updateBookRequest, 
    deleteBookRequest, 
    deleteBooksRequest 
} from '@/api/book-api'
import { ElMessage, ElMessageBox } from 'element-plus'

// 时间快照
const shortcuts = [
    {
        text: '1个月前',
        value: () => {
            const now = new Date()
            now.setMonth(now.getMonth() - 1)
            return now
        },
    },
    {
        text: '3个月前',
        value: () => {
            const now = new Date()
            now.setMonth(now.getMonth() - 3)
            return now
        },
    },
    {
        text: '1年前',
        value: () => {
            const now = new Date()
            now.setFullYear(now.getFullYear() - 1)
            return now
        },
    }
]

// 作者集合
const authors = ref([])

// 多选集合
const multipleSelection = ref([])

// 计算属性：选中的id集合
const ids = computed(() => multipleSelection.value.map(book => book.id))

// 勾选事件触发
const handleSelectionChange = val => {
    multipleSelection.value = val
}

// 表格数据
const booksData = ref([])

// 条件参数
const queryForm = reactive({
    bookName: '',
    author: '',
    begin: '',
    end: ''
})

// 当前页码
const currentPage = ref(1)
// 每页数量
const pageSize = ref(10)
// 总数量
const total = ref(0)

// 作者集合查询渲染下拉菜单
const queryAuthors = () => {
    authorsRequest()
    .then(res => {
        if(res.code === 200) {
            authors.value = res.data
        }
    })
}

// 条件分页查询渲染表格
const queryPage = () => {
    booksPageRequest({
        currentPage: currentPage.value, 
        pageSize: pageSize.value,
        params: queryForm
    }).then(res => {
        if(res.code === 200) {
            booksData.value = res.data.records
            total.value = res.data.total
        }
    })
}

// 组件挂载(页面初始化)完成后，进行首次表格渲染
onMounted(() => {
    queryAuthors()
    queryPage()
})

// 条件查询
const onSubmit = () => {
    // 如果时间逻辑不对，提示用户
    if (queryForm.begin > queryForm.end) {
        ElMessage({
            message: '开始时间不能晚于结束时间',
            type: 'error'
        })
        return false
    }
    queryPage()
}

// 清空条件
const onReset = () => {
    queryForm.bookName = ''
    queryForm.author = ''
    queryForm.begin = ''
    queryForm.end = ''
    queryPage()
}

// 页码变化
const handleCurrentChange = () => {
    queryPage()
}

// 页面容量变化
const handleSizeChange = () => {
    // 回到第一页
    currentPage.value = 1
    queryPage()
}

// 新增/编辑表单是否弹出
const dialogFormVisible = ref(false)

// 表单的标题
const formTitle = ref('新增书籍')

// 表单数据
const bookForm = reactive({
    id: 0,
    bookName: '',
    author: '',
    description: '',
    price: 0,
    number: 1
})

// 校验规则
const rules = reactive({
    bookName: [
        {
            required: true,
            message: '书名不能为空', 
            trigger: 'blur'
        }
    ],
    author: [
        {
            required: true,
            message: '作者不能为空', 
            trigger: 'blur'
        }
    ]
})

// 校验结果对象
const rulesRef = ref()

// 打开新增
const openDialogForAdd = () => {
    formTitle.value = '新增书籍'
    dialogFormVisible.value = true
    // 这个方法对于首次打开对话框，需要延迟执行，也可以在关闭弹出层时清除校验
    // rulesRef.value.resetFields() 
}

// 编辑单个
const handleEdit = (index, row) => {
    formTitle.value = '编辑书籍'
    bookForm.id = row.id
    bookForm.bookName = row.bookName
    bookForm.author = row.author
    bookForm.description = row.description
    bookForm.price = row.price || 0
    bookForm.number = row.number || 1
    dialogFormVisible.value = true
}

// 提交
const toSave = () => {
    rulesRef.value.validate(valid => {
        if(valid) {
            doRequest()
        } else{
            return false
        }
    })
}

// 发送请求
const doRequest = () => {
    if(formTitle.value === '新增书籍') {
        addBookRequest(bookForm)
        .then(res => {
            ElMessage({
                message: res.msg || '新增书籍成功',
                type: res.code === 200 ? 'success' : 'error'
            })
            if(res.code === 200) {
                toClose()
                // 如果当前页数量不满，则刷新表格数据
                if (booksData.value.length < pageSize.value) {
                    queryPage()
                } else {
                    total.value ++
                }
            }
        })
    } else {
        updateBookRequest(bookForm)
        .then(res => {
            ElMessage({
                message: res.msg || '更新书籍成功',
                type: res.code === 200 ? 'success' : 'error'
            })
            if(res.code === 200) {
                // 修改数据
                booksData.value.forEach(book => {
                    if(book.id == bookForm.id) {
                        book.bookName = bookForm.bookName
                        book.author = bookForm.author
                        book.description = bookForm.description
                        book.price = bookForm.price
                        book.number = bookForm.number
                    }
                })
                toClose()
            }
        })
    }
}

// 关闭
const toClose = () => {
    // 清除字段内容和校验信息
    rulesRef.value.resetFields()
    // 修改表单数据必须放到resetFields之后
    bookForm.id = 0
    bookForm.bookName = ''
    bookForm.author = ''
    bookForm.description = ''
    bookForm.price = 0
    bookForm.number = 1
    // 隐藏弹出层
    dialogFormVisible.value = false
}

// 删除单个
const handleDelete = (index, row) => {
    deleteBookRequest(row.id)
    .then(res => {
        ElMessage({
            message: res.msg || '删除书籍成功',
            type: res.code === 200 ? 'success' : 'error'
        })
        if (res.code === 200) {
            // 刷新当前数据
            queryPage()
        }
    })
}

// 批量删除确认
const toDeleteBatch = () => {
    ElMessageBox.confirm('确定删除选中的所有书籍吗?', '确认删除',{
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }
  )
    .then(() => {
        deleteBooks()
    })
    .catch(() => {
        ElMessage({
            type: 'info',
            message: '取消删除',
        })
    })
}

// 批量删除
const deleteBooks = () => {
    if (ids.value.length > 0) {
        deleteBooksRequest(ids.value)
        .then(res => {
            ElMessage({
                message: res.msg || '批量删除成功',
                type: res.code === 200 ? 'success' : 'error'
            })
            if (res.code === 200) {
                // 刷新当前数据
                queryPage()
            }
        })
    } else {
        ElMessage({
            message: '请勾选后再操作',
            type: 'error'
        })
    }
}

// 刷新当前页
const refresh = () => {
    queryPage()
}
</script>

<style scoped>
.demo-form-inline .el-input {
    --el-input-width: 220px;
}

.demo-form-inline .el-select {
    --el-select-width: 220px;
}
</style>